﻿using CompanyManageSystem.DLL;
using CompanyManageSystem.Model;
using EntityFramework.Extensions;
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CompanyManageSystem.Service
{
    public class RepastService
    {
        PSContext _db;
        public RepastService()
        {
            _db = new PSContext();
        }

        #region 物料
        /// <summary>
        /// 获取所有物料
        /// </summary>
        /// <returns></returns>
        public List<Material> GetAllMaterial()
        {
            return _db.Materials.OrderBy(p => p.Code).ToList();
        }

        /// <summary>
        /// 根据ID获取物料名称
        /// </summary>
        /// <param name="materialId"></param>
        /// <returns></returns>
        public string GetMaterialNameByID(Guid materialId)
        {
            return _db.Materials.Where(p => p.ID == materialId).Select(p => p.Name).FirstOrDefault();
            //return _db.Materials.Include(p => p.Name).Where(p => p.ID == materialId).Select(p => p.Name).FirstOrDefault();
        }

        /// <summary>
        /// 根据ID获取物料名称
        /// </summary>
        /// <param name="materialId"></param>
        /// <returns></returns>
        public string GetMaterialUnitByID(Guid materialId)
        {
            var unitId = _db.Materials.Where(p => p.ID == materialId).Select(p => p.UnitID).FirstOrDefault();
            var unit = _db.Units.Where(p => p.ID == unitId).Select(p => p.Name).FirstOrDefault();
            return unit;
        }

        /// <summary>
        /// 获取所有物料分类
        /// </summary>
        /// <returns></returns>
        public List<BaseElement> GetAllMaterialCategory()
        {
            return _db.MaterialCategorys.ToList();
        }

        /// <summary>
        /// 根据分类ID获取物料
        /// </summary>
        /// <returns></returns>
        public List<Material> GetMaterialByCatetoryID(Guid categoryId)
        {
            return _db.Materials.Where(p => p.CategoryID == categoryId).OrderBy(p => p.CreateTime).ToList();
        }

        /// <summary>
        /// 根据物料ID获取物料
        /// </summary>
        /// <returns></returns>
        public Material GetMaterialByID(Guid materialId)
        {
            return _db.Materials.Find(materialId);
        }

        /// <summary>
        /// 添加物料
        /// </summary>
        /// <param name="code"></param>
        /// <param name="name"></param>
        /// <param name="unitId"></param>
        /// <param name="price"></param>
        /// <param name="categoryId"></param>
        public void AddMaterial(string code, string name, Guid unitId, string place, Guid supplierId, Guid categoryId)
        {
            var materail = new Material
            {
                ID = Guid.NewGuid(),
                Code = code,
                Name = name,
                UnitID = unitId,
                Place = place,
                SupplierID = supplierId,
                CategoryID = categoryId,
                CreateTime = DateTime.Now
            };
            _db.Materials.Add(materail);
            _db.SaveChanges();
        }

        /// <summary>
        /// 编辑物料
        /// </summary>
        /// <param name="code"></param>
        /// <param name="name"></param>
        /// <param name="unitId"></param>
        /// <param name="price"></param>
        /// <param name="materialId"></param>
        /// <returns></returns>
        public Material UpdateMaterial(string code, string name, Guid unitId, string place, Guid supplierId, Guid materialId)
        {
            Material material = _db.Materials.Find(materialId);
            material.Code = code;
            material.Name = name;
            material.UnitID = unitId;
            material.Place = place;
            material.SupplierID = supplierId;
            _db.SaveChanges();
            return material;
        }

        /// <summary>
        /// 删除物料
        /// </summary>
        /// <param name="materialId"></param>
        /// <returns></returns>
        public int DelMaterial(Guid[] materialId)
        {
            return _db.Materials.Where(p => materialId.Contains(p.ID)).Delete();
        }
        #endregion

        #region 单位
        /// <summary>
        /// 获取所有单位
        /// </summary>
        /// <returns></returns>
        public List<Unit> GetAllUnit()
        {
            return _db.Units.OrderBy(p => p.CreateTime).ToList();
        }

        /// <summary>
        /// 根据ID获取单位
        /// </summary>
        /// <returns></returns>
        public Unit GetUnitByID(Guid? unitId)
        {
            return _db.Units.Find(unitId);
        }

        /// <summary>
        /// 添加单位
        /// </summary>
        /// <param name="code"></param>
        /// <param name="name"></param>
        public void AddUnit(string code, string name)
        {
            Unit unit = new Unit
            {
                ID = Guid.NewGuid(),
                Code = code,
                Name = name,
                CreateTime = DateTime.Now
            };
            _db.Units.Add(unit);
            _db.SaveChanges();
        }

        /// <summary>
        /// 编辑单位
        /// </summary>
        /// <returns></returns>
        public Unit UpdateUnit(string code, string name, Guid? unitId)
        {
            Unit unit = _db.Units.Find(unitId);
            unit.Code = code;
            unit.Name = name;
            _db.SaveChanges();
            return unit;
        }

        /// <summary>
        /// 删除单位
        /// </summary>
        /// <returns></returns>
        public int DelUnit(Guid[] unitId)
        {
            return _db.Units.Where(p => unitId.Contains(p.ID)).Delete();
        }
        #endregion

        #region 饭堂
        public List<Canteen> GetAllCanteen()
        {
            return _db.Canteens.OrderBy(p => p.Code).ToList();
        }
        #endregion

        #region 档口
        public List<Stall> GetAllStall()
        {
            return _db.Stalls.OrderBy(p => p.Code).ToList();
        }
        #endregion

        #region 供应商
        /// <summary>
        /// 获取所有供应商分类
        /// </summary>
        /// <returns></returns>
        public List<BaseElement> GetAllSupplierCategory()
        {
            return _db.SuppliersCategorys.ToList();
        }

        /// <summary>
        /// 获取所有供应商
        /// </summary>
        /// <returns></returns>
        public List<Supplier> GetAllSuppliers()
        {
            return _db.Suppliers.OrderBy(p => p.Name).ToList();
        }

        /// <summary>
        /// 根据分类ID获取供应商
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public List<Supplier> GetSupplierByCategoryID(Guid id)
        {
            return _db.Suppliers.Where(p => p.CategoryID == id).OrderBy(p => p.EnterTime).ToList();
        }

        /// <summary>
        /// 根据供应商ID获取供应商
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public Supplier GetSupplierByID(Guid id)
        {
            return _db.Suppliers.Where(p => p.ID == id).FirstOrDefault();
        }

        /// <summary>
        /// 添加供应商
        /// </summary>
        /// <param name="categoryID"></param>
        /// <param name="code"></param>
        /// <param name="name"></param>
        /// <param name="contracts"></param>
        /// <param name="phone"></param>
        /// <param name="address"></param>
        /// <returns></returns>
        public Guid AddSupplier(Guid categoryID, string code, string name, string contracts, string phone, string address)
        {
            Supplier supplier = new Supplier
            {
                ID = Guid.NewGuid(),
                Code = code,
                Name = name,
                Contracts = contracts,
                Phone = phone,
                Address = address,
                EnterTime = DateTime.Now,
                CategoryID = categoryID,
                IsChecked = false,
            };
            _db.Suppliers.Add(supplier);
            _db.SaveChanges();
            return supplier.ID;
        }

        /// <summary>
        /// 编辑供应商
        /// </summary>
        /// <param name="id"></param>
        /// <param name="code"></param>
        /// <param name="name"></param>
        /// <param name="address"></param>
        /// <param name="contracts"></param>
        /// <param name="phone"></param>
        /// <returns></returns>
        public Supplier UpdateSupplier(Guid id, string code, string name, string contracts, string phone, string address)
        {
            var supplier = _db.Suppliers.Where(p => p.ID == id).FirstOrDefault();
            supplier.Code = code;
            supplier.Name = name;
            supplier.Address = address;
            supplier.Contracts = contracts;
            supplier.Phone = phone;
            _db.SaveChanges();
            return supplier;
        }

        /// <summary>
        /// 根据勾选的CheckBox和分类ID删除供应商
        /// </summary>
        /// <param name="categoryID"></param>
        /// <param name="id"></param>
        /// <returns></returns>
        public int DelSupplierByCheckedID(Guid categoryID, Guid[] id)
        {
            return _db.Suppliers.Where(p => p.CategoryID == categoryID && id.Contains(p.ID)).Delete();
        }

        /// <summary>
        /// 获取供应商图片
        /// </summary>
        public List<byte[]> GetSupplierPicture(Guid supplierId)
        {
            return _db.AllPictures.Where(p => p.SourceID == supplierId && p.Category == 1).OrderBy(p => p.CreateTime).Select(p => p.Picture).ToList();
        }

        /// <summary>
        /// 添加供应商图片
        /// </summary>
        public void AddSupplierPicture(Guid supplierId, byte[] pByte)
        {
            var pic = new AllPicture
            {
                ID = Guid.NewGuid(),
                Picture = pByte,
                SourceID = supplierId,
                Category = 1,
                CreateTime = DateTime.Now
            };
            _db.AllPictures.Add(pic);
            _db.SaveChanges();
        }

        /// <summary>
        /// 删除供应商图片
        /// </summary>
        public int DelSupplierPicture(Guid supplierId)
        {
            return _db.AllPictures.Where(p => p.SourceID == supplierId && p.Category == 1).Delete();
        }

        /// <summary>
        /// 根据勾选删除供应商图片
        /// </summary>
        /// <returns></returns>
        public int DelSupplierpictureByCheck(Guid[] supplierId)
        {
            return _db.AllPictures.Where(p => supplierId.Contains(p.SourceID) && p.Category == 1).Delete();
        }
        #endregion

        #region 采购入库
        /// <summary>
        /// 获取当天所有采购订货单明细
        /// </summary>
        /// <returns></returns>
        public List<PurchaseOrderDetail> GetAllOrderDetailOnTheDay()
        {
            var date = DateTime.Now.Date;
            return _db.PurchaseOrderDetails.Where(p => DbFunctions.TruncateTime(p.CreateTime) == date).OrderBy(p => p.CreateTime).ToList();
        }

        /// <summary>
        /// 根据各种条件获取采购订货明细
        /// </summary>
        /// <param name="name"></param>
        /// <param name="code"></param>
        /// <param name="stallId"></param>
        /// <param name="canteenId"></param>
        /// <returns></returns>
        public List<PurchaseOrderDetail> GetOrderDetailByFactor(string name, string code, Guid? stallId, Guid? canteenId)
        {
            var date = DateTime.Now.Date;
            var canteen = "";
            var stall = "";

            if (canteenId != null)
            {
                canteen = _db.Canteens.Find(canteenId).Name;
            }
            if (stallId != null)
            {
                stall = _db.Stalls.Find(stallId).Name;
            }

            var data = _db.PurchaseOrderDetails
                .Join(_db.Materials, p => p.MaterialID, p => p.ID, (a, b) => new { a, b })
                .WhereIf(!string.IsNullOrEmpty(stall), p => p.a.Stall == stall)
                .WhereIf(!string.IsNullOrEmpty(canteen), p => p.a.Canteen == canteen)
                .Where(p => DbFunctions.TruncateTime(p.a.CreateTime) == date)
                .Where(p => p.a.MaterialName.Contains(name))
                .Where(p => p.b.Code.Contains(code))
                .Select(p => p.a)
                .ToList();
            return data;
        }

        /// <summary>
        /// 根据各种条件获取采购入库明细
        /// </summary>
        /// <param name="header"></param>
        public List<PurchaseStorageOrderDetail> GetStorageDetailByFactor(Guid[] headerId, DateTime date1, DateTime date2, DateTime date3, DateTime date4, Guid? supplierId, string style, string orderNum)
        {
            var data = _db.PurchaseStorageOrders
                .Join(_db.PurchaseStorageOrderDetails, p => p.ID, p => p.PurchaseStorageOrderID, (a, b) => new { a, b })
                .WhereIf(date1 != DateTime.MinValue, p => DbFunctions.TruncateTime(p.a.CreateTime) >= date1)
                .WhereIf(date2 != DateTime.MinValue, p => DbFunctions.TruncateTime(p.a.CreateTime) <= date2)
                .WhereIf(date3 != DateTime.MinValue, p => DbFunctions.TruncateTime(p.a.CreateTime) >= date3)
                .WhereIf(date4 != DateTime.MinValue, p => DbFunctions.TruncateTime(p.a.CreateTime) <= date4)
                .WhereIf(!string.IsNullOrEmpty(style), p => p.a.Style == (style == "现金" ? "0" : "1"))
                .WhereIf(!string.IsNullOrEmpty(supplierId.ToString()), p => p.a.SupplierID == supplierId)
                .WhereIf(headerId.Count() != 0, p => headerId.Contains(p.a.ID))
                .Where(p => p.a.OrderNum.Contains(orderNum))
                .Select(p => p.b)
                .OrderBy(p => p.CreateTime)
                .ToList();
            return data;
        }

        /// <summary>
        /// 根据各种条件获取采购入库主单
        /// </summary>
        /// <returns></returns>
        public List<PurchaseStorageOrder> GetStorageOrderByFactor(DateTime date1, DateTime date2, DateTime date3, DateTime date4, Guid? supplierId, string style, string orderNum)
        {
            var data = _db.PurchaseStorageOrders
                .WhereIf(date1 != DateTime.MinValue, p => DbFunctions.TruncateTime(p.CreateTime) >= date1)
                .WhereIf(date2 != DateTime.MinValue, p => DbFunctions.TruncateTime(p.CreateTime) <= date2)
                .WhereIf(date3 != DateTime.MinValue, p => DbFunctions.TruncateTime(p.CreateTime) >= date3)
                .WhereIf(date4 != DateTime.MinValue, p => DbFunctions.TruncateTime(p.CreateTime) <= date4)
                .WhereIf(!string.IsNullOrEmpty(style), p => p.Style == (style == "现金" ? "0" : "1"))
                .WhereIf(!string.IsNullOrEmpty(supplierId.ToString()), p => p.SupplierID == supplierId)
                .Where(p => p.OrderNum.Contains(orderNum))
                .OrderBy(p => p.CreateTime)
                .ToList();

            data.ForEach(p =>
            {
                p.Examine = p.Examine == "0" ? "未审批" : "已审批";
                p.Style = p.Style == "0" ? "现金" : "月结";
            });
            return data;
        }

        /// <summary>
        /// 获取所有采购入库明细
        /// </summary>
        /// <returns></returns>
        public List<PurchaseStorageOrderDetail> GetAllPurchaseStorageDetail()
        {
            return _db.PurchaseStorageOrderDetails.OrderBy(p => p.CreateTime).ToList();
        }

        /// <summary>
        /// 根据ID获取采购入库主单
        /// </summary>
        /// <returns></returns>
        public PurchaseStorageOrder GetPurcahseOrderByID(Guid? headerId)
        {
            return _db.PurchaseStorageOrders.Find(headerId);
        }

        /// <summary>
        /// 根据主单ID获取采购入库明细
        /// </summary>
        /// <returns></returns>
        public List<PurchaseStorageOrderDetail> GetPurcahseStorageDetailByHeaderID(Guid? headerId)
        {
            return _db.PurchaseStorageOrderDetails.Where(p => p.PurchaseStorageOrderID == headerId).ToList();
        }

        /// <summary>
        /// 添加新的采购入库明细
        /// </summary>
        /// <param name="list"></param>
        public void AddStorageOrder(List<PurchaseStorageOrderDetail> list, Guid headerId)
        {
            foreach (var item in list)
            {
                item.ID = Guid.NewGuid();
                item.CreateTime = DateTime.Now;
                item.PurchaseStorageOrderID = headerId;
                _db.PurchaseStorageOrderDetails.Add(item);
            }
            _db.SaveChanges();
        }

        /// <summary>
        /// 根据跳转个数和每页显示数获取采购入库主单
        /// </summary>
        /// <returns></returns>
        public List<PurchaseStorageOrder> GetPurchaseOrderBySelect(int skipNum, int pageSize)
        {
            var data = _db.PurchaseStorageOrders.OrderBy(p => p.CreateTime).Skip(skipNum).Take(pageSize).ToList();

            foreach (var item in data)
            {
                item.Style = item.Style == "0" ? "现金" : "月结";
                item.Examine = item.Examine == "0" ? "未审批" : "已审批";
            }

            return data;
        }

        /// <summary>
        /// 根据ID删除采购入库主单
        /// </summary>
        /// <returns></returns>
        public int DelPurchaseOrderByID(Guid[] headerId)
        {
            //删除主单里面的明细
            _db.PurchaseStorageOrderDetails.Where(p => headerId.Contains(p.PurchaseStorageOrderID)).Delete();
            return _db.PurchaseStorageOrders.Where(p => headerId.Contains(p.ID)).Delete();
        }

        /// <summary>
        /// 根据主单ID删除采购入库明细
        /// </summary>
        /// <param name="header"></param>
        /// <returns></returns>
        public int DelPurchaseDetailByHeaderID(Guid? headerId)
        {
            return _db.PurchaseStorageOrderDetails.Where(p => p.PurchaseStorageOrderID == headerId).Delete();
        }

        /// <summary>
        /// 根据主单获取主单里面的所有明细
        /// </summary>
        /// <returns></returns>
        public List<PurchaseStorageOrderDetail> GetPurchaseStorageDetailByHeader(List<PurchaseStorageOrder> header)
        {
            var headerId = header.Select(p => p.ID).ToArray();
            var data = _db.PurchaseStorageOrderDetails
                .Where(p => headerId.Contains(p.PurchaseStorageOrderID)).ToList();
            return data;
        }

        /// <summary>
        /// 根据主单列更改审批状态(0:弃审 1:审批)
        /// </summary>
        /// <param name="num"></param>
        public void ChangeExamineStatus(string num, List<PurchaseStorageOrder> header)
        {
            header.ForEach(p =>
            {
                _db.PurchaseStorageOrders.Find(p.ID).Examine = num;
            });

            _db.SaveChanges();
        }

        /// <summary>
        /// 根据主单ID更改审批状态(0:弃审 1:审批)
        /// </summary>
        public void ChangeExamineStatusByID(Guid? headerId, string num)
        {
            var header = _db.PurchaseStorageOrders.Find(headerId);
            header.Examine = num;
            _db.SaveChanges();
        }

        /// <summary>
        /// 上一张采购入库主单
        /// </summary>
        /// <param name="headerId"></param>
        /// <returns></returns>
        public PurchaseStorageOrder GetPrevPurchaseStorageOrder(DateTime time)
        {
            var header = _db.PurchaseStorageOrders.Where(p => p.CreateTime < time).OrderByDescending(p => p.CreateTime).FirstOrDefault();
            return header;
        }

        /// <summary>
        /// 下一张采购入库单
        /// </summary>
        /// <param name="time"></param>
        /// <returns></returns>
        public PurchaseStorageOrder GetNextPurchaseStorageOrder(DateTime time)
        {
            var header = _db.PurchaseStorageOrders.Where(p => p.CreateTime > time).OrderBy(p => p.CreateTime).FirstOrDefault();
            return header;
        }
        #endregion

        #region 供应商财务
        public List<SupplierFinance> GetSupplierFinanceByFactor(DateTime date1,DateTime date2,Guid? supplierId)
        {
            var minTime = DateTime.MinValue;
            //获取月第一天
            date1 = date1.AddDays(1 - date1.Day);
            //获取月最后一天
            date2 = date2.AddDays(1 - date2.Day).AddMonths(1).AddDays(-1);
            return _db.SupplierFinances
                      .OrderBy(p => p.CreateTime)
                      .WhereIf(date1 != minTime.AddDays(1 - minTime.Day),p => DbFunctions.TruncateTime(p.PaidTime) >= date1)
                      .WhereIf(date2 != minTime.AddDays(1 - minTime.Day).AddMonths(1).AddDays(-1), p => DbFunctions.TruncateTime(p.PaidTime) <= date2)
                      .WhereIf(supplierId != Guid.Empty,p => p.SupplierID == supplierId)
                      .ToList();
        }

        /// <summary>
        /// 添加供应商财务
        /// </summary>
        public void AddSupplierFinance(Guid supplierId, string supplierName, DateTime paidTime, decimal money, string remark)
        {
            SupplierFinance finance = new SupplierFinance
            {
                ID = Guid.NewGuid(),
                SupplierID = supplierId,
                SupplierName = supplierName,
                PaidTime = paidTime,
                Money = money,
                Remark = remark,
                CreateTime = DateTime.Now
            };
            _db.SupplierFinances.Add(finance);
            _db.SaveChanges();
        }


        #endregion

    }
}
